//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
// 
// You should have received a copy of the GNU Lesser General Public License
// along with this program.  If not, see http://www.gnu.org/licenses/.
// 

#include "FilePiece.h"
#include "FileBlock.h"
#include <omnetpp.h>

namespace peermaliziosi {

long FilePiece::countConstructors=0;
long FilePiece::countDestructors=0;

FilePiece::FilePiece() {

    cModule *sysM= simulation.getSystemModule();
    numBlocks= sysM->par("numBlocks").longValue();
    blocks = new FileBlock[numBlocks];
    countBlocks= 0;

    countConstructors++;
}

FilePiece::~FilePiece() {
    delete []blocks;
    countDestructors++;
}

int FilePiece::getNumBlocks() {
    return numBlocks;
}

bool FilePiece::havePiece(){
    // restituisco true se tutti i blocchi di questo pezzo sono a true
    return (countBlocks==numBlocks);
}

bool FilePiece::haveBlock(int blockIndex) {
    if (checkIndex(blockIndex)) {
        return blocks[blockIndex].haveBlock();
    } else {
        throw std::range_error("Indice di blocco errato");
    }
}

bool FilePiece::setBlock(int blockIndex) {
    if (checkIndex(blockIndex)) {
        bool ret= blocks[blockIndex].setBlock(true);
        if (!ret) {
            // se non avevo questo blocco, incremento il contatore
            countBlocks++;
        }
        return ret;
    } else {
        throw std::range_error("Indice di blocco errato");
    }
}

bool FilePiece::checkIndex(int blockIndex) {
    if (0<=blockIndex && blockIndex<numBlocks) {
        return true;
    } else {
        return false;
    }
}

/* Segna tutti i blocchi di questo pezzo come gia' ottenuti*/
bool FilePiece::setTrueAllPieceBlocks(){

    bool ret= true; // avevo questo pezzo?
    for (int k=0; k<numBlocks; k++) {
        bool ret2= blocks[k].setBlock(true);
        if (!ret2) {
            // se non avevo questo blocco, incremento il contatore
            countBlocks++;
            ret= false;
        }
    }
    return ret;
}

/* Segna tutti i blocchi di questo pezzo come non ottenuti*/
bool FilePiece::setFalseAllPieceBlocks(){

    bool ret= true; // avevo questo pezzo?
    for (int k=0; k<numBlocks; k++) {
        bool ret2= blocks[k].setBlock(false);
        if (ret2) {
            // se avevo questo blocco, decremento il contatore
            countBlocks--;
        } else {
            ret= false;
        }
    }
    return ret;
}


}
